﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Newtonsoft.Json;
using System.IO;
using System.Web;
using Aspose.Cells;
using System.Text.RegularExpressions;
using System.Threading;
using Tentcent.Ai.Sdk;

namespace 驾驶证识别
{
    public partial class Form1 : Form
    {
        public static string model = "https://aip.baidubce.com/rest/2.0/ocr/v1/general_basic?access_token=";
        public static string Key1 = "PhrYH1YviZWdG7yaTqYDNEGB";
        public static string Key2 = "2lysX4kqRBbXBxCiO6VlU6SLYzROzRYT";
        public static string FileParh = "";
        public static string outputFileParh = "";

        public Form1 ( )
        {
            InitializeComponent();
        }

        private void Form1_Load ( object sender, EventArgs e )
        {



        }



        public void Progress ( )
        {
            string token = GetToken();
            string ExcelFile = Path.GetFullPath("excel/mod.xlsx");
            Workbook WB = new Workbook(ExcelFile);
            Worksheet WS = WB.Worksheets[0];




            int cellrow = 1;
            string imageinfo = "";
            string[] FileArry = Directory.GetFiles(FileParh);
            IEnumerable<string> Files = FileArry.Where(o => o.Contains("jpg"));





            foreach (string f in Files)
            {
                try
                {
                    BaiduToken BT = JsonConvert.DeserializeObject<BaiduToken>(token);
                    string base64 = ImgToBase64(f);
                    imageinfo = GetImageInfo(BT, base64);
                    BaiduResult BR = JsonConvert.DeserializeObject<BaiduResult>(imageinfo);


                    string CarNo = GetData(imageinfo, new List<string>() { "粤[A-z,0-9]+", "B[A-z,0-9]+" });
                    string CarType = GetData(imageinfo, new List<string>() { "类型[\u4e00-\u9fa5]+", "类.?[\u4e00-\u9fa5]+", "[大中小低城牵普轻][\u4e00-\u9fa5]+车" });
                    string Owner = GetData(imageinfo, new List<string>() { "所有人[\u4e00-\u9fa5]+", "所.?人[\u4e00-\u9fa5]+", "深圳[\u4e00-\u9fa5,A-z,0-9]+司" });
                    string CarAttr = GetData(imageinfo, new List<string>() { "使用性质[\u4e00-\u9fa5]{4}", "使用[\u4e00-\u9fa5]{6}" });
                    string CarVIN = GetData(imageinfo, new List<string>() { "L[A-z,0-9]{7}[A-z,0-9]+", "识别代号[\u4e00-\u9fa5,A-z,0-9,()]+", "识别代号.?[\u4e00-\u9fa5,A-z,0-9,()]+", "[A-z,0-9]{11}[A-z,0-9]+" });
                    string RegData = GetData(imageinfo, new List<string>() { "注册日期[A-z,0-9,-]+", "([0-9]{3}[1-9]|[0-9]{2}[1-9][0-9]{1}|[0-9]{1}[1-9][0-9]{2}|[1-9][0-9]{3})-(((0[13578]|1[02])-(0[1-9]|[12][0-9]|3[01]))|((0[469]|11)-(0[1-9]|[12][0-9]|30))|(02-(0[1-9]|[1][0-9]|2[0-8])))" });
                    string IssuData = GetData(imageinfo, new List<string>() { "发证日期[A-z,0-9,-]+", "发.{2}期[A-z,0-9,-]+" });
                    string hhhh = GetData(imageinfo, new List<string>() { "比亚迪[\u4e00-\u9fa5,A-z,0-9,()]+", "比[\u4e00-\u9fa5,A-z,0-9,()]+", "BYD[\u4e00-\u9fa5,A-z,0-9,()]+" });



                    WS.Cells[cellrow, 0].PutValue(CarNo);
                    WS.Cells[cellrow, 1].PutValue(CarType);
                    WS.Cells[cellrow, 2].PutValue(Owner);
                    WS.Cells[cellrow, 3].PutValue(CarAttr);
                    WS.Cells[cellrow, 4].PutValue(hhhh);


                    WS.Cells[cellrow, 5].PutValue(CarVIN);
                    WS.Cells[cellrow, 6].PutValue(RegData);
                    WS.Cells[cellrow, 7].PutValue(IssuData);
                }
                catch
                {
                    WS.Cells[cellrow, 0].PutValue("数据获取出错");
                }

                WS.Cells[cellrow, 9].PutValue(f);
                WS.Cells[cellrow, 10].PutValue(imageinfo);
                cellrow++;
                SetProgressbar(cellrow);
            }


            WB.Save(outputFileParh + "\\驾驶证导出结果" + DateTime.Now.ToString("HH-mm-ss-ms") + ".xls");
            SetMessage("结果已导出到:" + outputFileParh + "\\驾驶证导出结果" + DateTime.Now.ToString("HH-mm-ss-ms") + ".xls");
        }

        public void BaiduAIProgress ( )
        {
            model = "https://aip.baidubce.com/rest/2.0/ocr/v1/vehicle_license?access_token=";

            string token = GetToken();
            string ExcelFile = Path.GetFullPath("excel/mod.xlsx");
            Workbook WB = new Workbook(ExcelFile);
            Worksheet WS = WB.Worksheets[0];

            int cellrow = 1;
            string imageinfo = "";
            string[] FileArry = Directory.GetFiles(FileParh);
            IEnumerable<string> Files = FileArry.Where(o => o.Contains("jpg"));

            foreach (string f in Files)
            {
                try
                {
                    BaiduToken BT = JsonConvert.DeserializeObject<BaiduToken>(token);
                    string base64 = ImgToBase64(f);
                    imageinfo = GetImageInfo(BT, base64);
                    BaiduAIresult BR = JsonConvert.DeserializeObject<BaiduAIresult>(imageinfo);


                    WS.Cells[cellrow, 0].PutValue(BR.words_result.号牌号码.words);
                    WS.Cells[cellrow, 1].PutValue(BR.words_result.车辆类型.words);
                    WS.Cells[cellrow, 2].PutValue(BR.words_result.所有人.words);
                    WS.Cells[cellrow, 3].PutValue(BR.words_result.使用性质.words);
                    WS.Cells[cellrow, 4].PutValue(BR.words_result.品牌型号.words);
                    WS.Cells[cellrow, 5].PutValue(BR.words_result.车辆识别代号.words);
                    WS.Cells[cellrow, 6].PutValue(BR.words_result.注册日期.words);
                    WS.Cells[cellrow, 7].PutValue(BR.words_result.发证日期.words);
                }
                catch (Exception w)
                {
                    WS.Cells[cellrow, 0].PutValue("数据获取出错");
                }

                WS.Cells[cellrow, 9].PutValue(f);
                WS.Cells[cellrow, 10].PutValue(imageinfo);
                cellrow++;
                SetProgressbar(cellrow);


            }


            WB.Save(outputFileParh + "\\驾驶证导出结果" + DateTime.Now.ToString("HH-mm-ss-ms") + ".xls");

            SetMessage("结果已导出到:"+outputFileParh + "\\驾驶证导出结果" + DateTime.Now.ToString("HH-mm-ss-ms") + ".xls");
        }


        public void CheckFileType()
        {
            if (string.IsNullOrEmpty(FileParh))
            {
                MessageBox.Show("未选择文件夹！");
            }
            if (!Directory.Exists(FileParh + "\\行驶证"))
            {
                Directory.CreateDirectory(FileParh + "\\行驶证");
            }
            if (!Directory.Exists(FileParh + "\\其他"))
            {
                Directory.CreateDirectory(FileParh + "\\其他");
            }
            int cellrow = 0;
            foreach (string F in Directory.GetFiles(FileParh))
            {
                try
                {
                    Dictionary<string, string> dic = new Dictionary<string, string>();

                    if (Key1 != "PhrYH1YviZWdG7yaTqYDNEGB" && Key2 != "2lysX4kqRBbXBxCiO6VlU6SLYzROzRYT")
                    {
                        dic.Add("app_id", Key1);
                        dic.Add("key", Key2);
                    }
                    else
                    {
                        dic.Add("app_id", "2111009814");
                        dic.Add("key", "o1jagpBwqYwqwXnH");
                    }

                dic.Add("image", ImgToBase64(F));
                string data = OcrServer.GenJson(dic);
                if (!string.IsNullOrEmpty(data))
                {

                        string licence = GetData(data, new List<string>() { "行驶证","行[\u4e00-\u9fa5]?证", "中华人民共和国行驶证", "中华[\u4e00-\u9fa5]+驶证","公安局交","通警察支队"});
                        if (string.IsNullOrEmpty(licence))
                        {
                            List<string> LInfo = new List<string>();

                            LInfo.Add(GetData(data, new List<string>() { "粤[A-z,0-9]+", "B[A-z,0-9]+" }));
                            LInfo.Add(GetData(data, new List<string>() { "类型[\u4e00-\u9fa5]+", "类.?[\u4e00-\u9fa5]+", "[大中小低城牵普轻][\u4e00-\u9fa5]+车" }));
                            LInfo.Add((GetData(data, new List<string>() { "所有人[\u4e00-\u9fa5]+", "所.?人[\u4e00-\u9fa5]+", "深圳[\u4e00-\u9fa5,A-z,0-9]+司" })));
                            LInfo.Add(GetData(data, new List<string>() { "使用性质[\u4e00-\u9fa5]{4}", "使用[\u4e00-\u9fa5]{6}" }));
                            LInfo.Add(GetData(data, new List<string>() { "L[A-z,0-9]{7}[A-z,0-9]+", "识别代号[\u4e00-\u9fa5,A-z,0-9,()]+", "识别代号.?[\u4e00-\u9fa5,A-z,0-9,()]+", "[A-z,0-9]{11}[A-z,0-9]+" }));
                            LInfo.Add(GetData(data, new List<string>() { "注册日期[A-z,0-9,-]+", "([0-9]{3}[1-9]|[0-9]{2}[1-9][0-9]{1}|[0-9]{1}[1-9][0-9]{2}|[1-9][0-9]{3})-(((0[13578]|1[02])-(0[1-9]|[12][0-9]|3[01]))|((0[469]|11)-(0[1-9]|[12][0-9]|30))|(02-(0[1-9]|[1][0-9]|2[0-8])))" }));
                            LInfo.Add(GetData(data, new List<string>() { "发证日期[A-z,0-9,-]+", "发.{2}期[A-z,0-9,-]+" }));
                            LInfo.Add(GetData(data, new List<string>() { "比亚迪[\u4e00-\u9fa5,A-z,0-9,()]+", "比[\u4e00-\u9fa5,A-z,0-9,()]+", "BYD[\u4e00-\u9fa5,A-z,0-9,()]+" }));

                            if (LInfo.Where(o => (!string.IsNullOrEmpty(o))).Count() >= 5)
                            {
                                licence = "行驶证";
                            }



                            List<string> WrongIngfo = new List<string>() {
                               GetData(data, new List<string>() { "身份证","身[\u4e00-\u9fa5]?证" }),
                               GetData(data, new List<string>() { "发票","抵扣联","机动车销售","开票日期","发票号码" }),
                               GetData(data, new List<string>() { "营业执照" ,"成立时间"}),
                               GetData(data, new List<string>() { "合同" }),
                            };
                            if (WrongIngfo.Where(o => (!string.IsNullOrEmpty(o))).Count() > 0)
                            {
                                licence = null;
                            }



                        }






                        if (!string.IsNullOrEmpty(licence))
                        {

                            Thread.Sleep(100);
                            File.Move(F, FileParh + "\\行驶证\\" + Path.GetFileName(F));

                        }
                        else
                        {
                            Thread.Sleep(100);
                            File.Move(F, FileParh + "\\其他\\" + Path.GetFileName(F));
                        }



                }
                }
                catch(Exception e)
                {
                    //SetMessage(e.Message);
                }
                cellrow++;
                SetProgressbar(cellrow);


            }
            SetMessage("处理完毕！");

        }


        public string ImgToBase64 ( string FileUrl )
        {
            string OutPut = "";
            try
            {
                Bitmap BM = new Bitmap(FileUrl);
                MemoryStream MS = new MemoryStream();
                BM.Save(MS, System.Drawing.Imaging.ImageFormat.Jpeg);
                byte[] BitArray = new byte[MS.Length];
                MS.Position = 0;
                MS.Read(BitArray, 0, (int)MS.Length);
                MS.Close();
                OutPut = Convert.ToBase64String(BitArray);
            }
            catch (Exception w)
            {

            }

            return OutPut;
        }


        public string GetData ( string Data, List<string> RegStr )
        {

            foreach (string regstr in RegStr)
            {
                Regex reg = new Regex(regstr);
                Match match = reg.Match(Data);
                if (match.Length > 0)
                {

                    if (string.IsNullOrEmpty(match.Groups[0].Value) && match.Length > 1)
                    {
                        return match.Groups[1].Value;
                    }
                    return match.Groups[0].Value;

                }
            }
            return null;
        }


        public static string UrlEncode ( string str )
        {
            StringBuilder sb = new StringBuilder();
            byte[] byStr = System.Text.Encoding.UTF8.GetBytes(str);
            for (int i = 0; i < byStr.Length; i++)
            {
                sb.Append(@"%" + Convert.ToString(byStr[i], 16));
            }
            return sb.ToString();
        }


        public string GetToken ( )
        {
            return httptest.GetHtml("https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials&client_id=" + Key1 + "&client_secret=" + Key2);
        }

        public string GetImageInfo ( BaiduToken BT, string ImageBase64 )
        {

            Dictionary<string, string> dic = new Dictionary<string, string>();
            dic.Add("image_type", "BASE64");
            dic.Add("group_id", "gropu001");
            dic.Add("user_id", "0001");
            dic.Add("image", UrlEncode(ImageBase64));
            string Url = model + BT.access_token;
            return Post(Url, dic);

        }
   
        public static string Post ( string url, Dictionary<string, string> dic )
        {
            string result = "";
            HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url);
            req.Method = "POST";
            req.ContentType = "application/x-www-form-urlencoded";
            StringBuilder builder = new StringBuilder();
            int i = 0;
            foreach (var item in dic)
            {
                if (i > 0)
                    builder.Append("&");
                builder.AppendFormat("{0}={1}", item.Key, item.Value);
                i++;
            }


            byte[] data = Encoding.UTF8.GetBytes(builder.ToString());
            req.ContentLength = data.Length;
            using (Stream reqStream = req.GetRequestStream())
            {
                reqStream.Write(data, 0, data.Length);
                reqStream.Close();
            }
            HttpWebResponse resp = (HttpWebResponse)req.GetResponse();
            Stream stream = resp.GetResponseStream();
            //获取响应内容
            using (StreamReader reader = new StreamReader(stream, Encoding.UTF8))
            {
                result = reader.ReadToEnd();
            }
            return result;
        }

        private void button1_Click ( object sender, EventArgs e )
        {
            //初始化一个OpenFileDialog类
            FolderBrowserDialog fileDialog = new FolderBrowserDialog() { ShowNewFolderButton = true };
            //判断用户是否正确的选择了文件
            if (fileDialog.ShowDialog() == DialogResult.OK)
            {
                textBox1.Text = fileDialog.SelectedPath;
                FileParh = fileDialog.SelectedPath;
                MessageBox.Show(string.Format("已选定:\"{0}\"\n路径内共有{1}个文件", new object[] { fileDialog.SelectedPath, Directory.GetFiles(FileParh).Length }));
                progressBar1.Maximum = Directory.GetFiles(FileParh).Where(o => o.Contains(".jpg")).Count();
            }
        }

        private void button2_Click ( object sender, EventArgs e )
        {
            //初始化一个OpenFileDialog类
            FolderBrowserDialog fileDialog = new FolderBrowserDialog() { ShowNewFolderButton = true };
            //判断用户是否正确的选择了文件
            if (fileDialog.ShowDialog() == DialogResult.OK)
            {
                textBox2.Text = fileDialog.SelectedPath;
                outputFileParh = fileDialog.SelectedPath;
                MessageBox.Show(string.Format("已选定:\"{0}\"\n路径为输出文件夹", new object[] { fileDialog.SelectedPath }));

            }
        }

        private void txbAPIKey_TextChanged ( object sender, EventArgs e )
        {
            Key1 = txbAPIKey.Text;
        }

        private void txbSecretKey_TextChanged ( object sender, EventArgs e )
        {
            Key2 = txbSecretKey.Text;
        }

        private void button3_Click ( object sender, EventArgs e )
        {
            Thread T = new Thread(( ) =>
            {
                Progress();
            });
            T.Start();
        }

        private void button4_Click ( object sender, EventArgs e )
        {
            model = "https://aip.baidubce.com/rest/2.0/ocr/v1/accurate_basic?access_token=";
            Thread T = new Thread(( ) =>
            {
                Progress();
            });
            T.Start();
        }

        private void button5_Click ( object sender, EventArgs e )
        {
            model = "https://aip.baidubce.com/rest/2.0/ocr/v1/accurate?access_token=";
            Thread T = new Thread(( ) =>
            {
                Progress();
            });
            T.Start();
        }

        private void button6_Click ( object sender, EventArgs e )
        {
            Thread T = new Thread(( ) =>
            {

                BaiduAIProgress();
            });
            T.Start();

        }

        private void backgroundWorker1_DoWork ( object sender, DoWorkEventArgs e )
        {

        }

        private void SetProgressbar ( int i )
        {
            if (this.InvokeRequired)
            {

                Action<int> Act = ( int Param ) => { SetProgressbar(Param); };
                this.Invoke(Act, new object[] { i });

            }
            else
            {
                labelProgress.Text = (i) + "/" + progressBar1.Maximum;

                if (i >= progressBar1.Maximum)
                {
                    progressBar1.Value = progressBar1.Maximum;
                }
                else {
                    progressBar1.Value = (int)i;
                }
            }

        }


        private void SetMessage ( string msg )
        {

            if (this.InvokeRequired)
            {
                Action<string> act = ( string param ) => { SetMessage(param); };
                this.Invoke(act, new object[] { msg });
            }
            else
            {
                MessageBox.Show(msg);
            }
        }

        private void button7_Click(object sender, EventArgs e)
        {
            progressBar1.Maximum = Directory.GetFiles(FileParh).Count();
            Thread T = new Thread(() =>
            {

                CheckFileType();
            });
            T.Start();

        }

        private void labelProgress_Click(object sender, EventArgs e)
        {

        }

        private void button8_Click(object sender, EventArgs e)
        {

            Dictionary<string, string> dic = new Dictionary<string, string>();
            dic.Add("app_id", "2111009814");
            dic.Add("key", "o1jagpBwqYwqwXnH");

            //dic.Add("app_id", "2108226413");
            //dic.Add("key", "4r7UhH7gi3jbOcet");
            dic.Add("image", ImgToBase64("F:\\AI1\\结果\\DB1-0-0000.jpg"));
            dic.Add("type", "0");
            var data=  OcrServer.Drvie(dic);








        }
    }

    public class BaiduToken
    {
        public string refresh_token { get; set; }
        public string expires_in { get; set; }
        public string session_key { get; set; }
        public string access_token { get; set; }
        public string scope { get; set; }
        public string session_secret { get; set; }
    }


    public class BaiduResult
    {


        public string log_id { get; set; }

        public string words_result_num { get; set; }





    }




    public class BaiduCommonResult : BaiduResult
    {

        public BaiduCommonResult ( )
        {
            words_result = new List<Wordsresult>();
        }
        public List<Wordsresult> words_result;
        public class Wordsresult
        {
            Wordsresult ( )
            {
                location = new Location();
            }
            public string words { get; set; }

            public Location location;

            public class Location
            {
                public float? width { get; set; }
                public float? top { get; set; }
                public float? left { get; set; }
                public float? height { get; set; }
            }
        }
    }


    public class BaiduAIresult : BaiduResult
    {
        public BaiduAIresult ( )
        {

            words_result = new wordsresult();


        }

        public wordsresult words_result;

        public string detect_direction { get; set; }
        public string accuracy { get; set; }
        public string direction { get; set; }





        public class wordsresult
        {
            public WR 品牌型号 { get; set; }
            public WR 发证日期 { get; set; }
            public WR 使用性质 { get; set; }
            public WR 发动机号码 { get; set; }
            public WR 号牌号码 { get; set; }
            public WR 所有人 { get; set; }
            public WR 住址 { get; set; }
            public WR 注册日期 { get; set; }
            public WR 车辆识别代号 { get; set; }
            public WR 车辆类型 { get; set; }

        }


        public class WR
        {
            public string words { get; set; }
        }


    }




}
